#include "../include/EventDispatcher.h"
#include <algorithm>

namespace NEvent {

    vector< EventDispatcher* > EventDispatcher::dispatcherContainer;

    EventDispatcher::EventDispatcher()
    {
        //ctor
        dispatcherContainer.push_back( this );
    }

    EventDispatcher::~EventDispatcher()
    {
        //dtor
        vector< EventDispatcher* >::iterator iter = find( dispatcherContainer.begin() , dispatcherContainer.end() , this );
        if ( iter != dispatcherContainer.end() ) {
            dispatcherContainer.erase( iter );
        }
    }

    void EventDispatcher::doAllDispatchersEvents()
    {
        for( size_t i = 0 ; i < dispatcherContainer.size() ; i ++ ) {
            dispatcherContainer[i]->doEvents();
        }
    }

    void EventDispatcher::dispatch( Event *evt )
    {
        m_event_list.push_back( evt );
    }

    void EventDispatcher::doEvents()
    {
        list<Event*>::iterator iter;
        Event *evt;
        for( iter = m_event_list.begin() ; iter != m_event_list.end(); iter ++ ) {
            evt = *iter;
            string _type = evt->getType();
            if ( m_listen_list.count( _type ) == 0 ) {
                continue;
            }
            list<struct listenNode> &_list = m_listen_list[ _type ];

            for( list<struct listenNode>::iterator iter = _list.begin() ; iter != _list.end() ; ) {
                struct listenNode & node = *iter;
                node.fn( evt );

                if ( node.once ) {
                    iter = _list.erase( iter );
                } else {
                    iter ++;
                }
            }

            if ( _list.size() == 0 ) {
                m_listen_list.erase( _type );
            }
        }
    }


    void EventDispatcher::addEventListener( string _type , EventDispatcher::EventFunction fn , bool once )
    {
        list<struct listenNode> &_list = m_listen_list[_type];

        for( list<struct listenNode>::iterator iter = _list.begin() ; iter != _list.end() ; iter ++ ) {
            struct listenNode &_node = *iter;
            if ( _node.fn == fn ) {
                //存在监听，不再重复添加
                return;
            }
        }

        struct listenNode node;
        node.fn = fn;
        node.once = once;

        _list.push_back( node );
    }

    void EventDispatcher::removeEventListener( string _type , EventDispatcher::EventFunction fn  )
    {
        if ( m_listen_list.count( _type ) == 0 ) {
            return;
        }

        list<struct listenNode> &_list = m_listen_list[_type];

        if ( _list.size() == 0 ) {
            return;
        }

        for( list<struct listenNode>::iterator iter = _list.begin() ; iter != _list.end() ; iter ++ ) {
            struct listenNode &_node = *iter;
            if ( _node.fn == fn ) {
                iter = _list.erase( iter );
                break;
            }
        }

        if ( _list.size() == 0 ) {
            m_listen_list.erase( _type );
        }
    }
}
